package com.woniu.utils;



import com.woniu.execption.TokenException;
import io.jsonwebtoken.Claims;
import io.jsonwebtoken.JwtBuilder;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.security.Keys;

import javax.crypto.SecretKey;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;

/**
 * JwtUtil 类用于生成和解析 JSON Web Tokens (JWT)。
 * JWT 是一种用于在网络上传输信息的开放标准 (RFC 7519)，通常用于身份验证。
 */
public class JwtUtil {
    
    // 用于签署管理员身份的密钥
    public static final String adminSecret = "jlsdjflsjflkjsdlfsdkldfnklsdnflsdnlksdkf";
    
    // 用于签署用户身份的密钥
    public static final String userSecret = "jlsdjfksdninfghfdgnkjnsuihfjsammjiaakiakaakakk";
    
    /**
     * 生成Token
     *
     * @param body   Token 的主体信息，以键值对的形式存储
     * @param time   Token 的有效期（秒）
     * @param secret 用于签署 Token 的密钥
     * @return 生成的 JWT
     */
    public static String createToken(Map<String, Object> body, Integer time, String secret) {
        SecretKey key = Keys.hmacShaKeyFor(secret.getBytes());
        JwtBuilder jb = Jwts.builder();
        // 检查主体信息是否存在
        if (body == null || body.size() <= 0) {
            throw new TokenException("没有数据",5001);
        }
        // 设置 Token 的主体信息
        jb.setClaims(body);
        // 设置 Token 的过期时间
        if (time == null) {
            jb.setExpiration(new Date(System.currentTimeMillis() + 60 * 30 * 1000));
        } else {
            jb.setExpiration(new Date(System.currentTimeMillis() + time * 1000));
        }
        // 使用密钥签署 Token 并返回
        return jb.signWith(key).compact();
    }
    
    /**
     * 生成Token，默认有效期为30分钟
     *
     * @param body   Token 的主体信息，以键值对的形式存储
     * @param secret 用于签署 Token 的密钥
     * @return 生成的 JWT
     */
    public static String createToken(Map<String, Object> body, String secret) {
        return createToken(body, null, secret);
    }
    
    /**
     * 解析 Token
     *
     * @param token  要解析的 JWT
     * @param secret 用于验证 Token 的密钥
     * @return 解析后的主体信息
     * @throws Exception 如果 Token 为空或解析失败，抛出异常
     */
    public static Claims parseToken(String token, String secret) throws Exception {
        if (token == null) {
            throw new TokenException("token为空",5002);
        }
        SecretKey key = Keys.hmacShaKeyFor(secret.getBytes());
        return Jwts.parserBuilder().setSigningKey(key).build().parseClaimsJws(token).getBody();
    }
    
    /**
     * 生成用户端Token
     *
     * @param body 用户身份信息
     * @return 生成的用户端 JWT
     */
    public static String createUserToken(Map<String, Object> body) {
        return createToken(body, userSecret);
    }
    
    /**
     * 生成用户端Token
     *
     * @param body 可变参数，用于构建用户身份信息
     * @return 生成的用户端 JWT
     */
    public static String createUserToken(Object... body) {
        if (body == null || body.length <= 0) {
            throw new TokenException("没有主体数据",5003);
        }
        Map<String, Object> maps = new HashMap<>();
        for (int i = 0; i < body.length; i += 2) {
            Object value = null;
            if (i + 1 < body.length) {
                value = body[i + 1];
            }
            maps.put(body[i].toString(), value);
        }
        return createToken(maps, userSecret);
    }
    
    /**
     * 生成管理员端Token
     *
     * @param body 管理员身份信息
     * @return 生成的管理员端 JWT
     */
    public static String createAdminToken(Map<String, Object> body) {
        return createToken(body, adminSecret);
    }
    
    /**
     * 生成管理员端Token
     *
     * @param body 可变参数，用于构建管理员身份信息
     * @return 生成的管理员端 JWT<dependency>
     *     <groupId>com.alibaba.cloud</groupId>
     *     <artifactId>spring-cloud-starter-alibaba-seata</artifactId>
     * </dependency>
     */
    public static String createAdminToken(Object... body) {
        if (body == null || body.length <= 0) {
            throw new TokenException("没有主体数据",5003);
        }
        Map<String, Object> maps = new HashMap<>();
        for (int i = 0; i < body.length; i += 2) {
            Object value = null;
            if (i + 1 < body.length) {
                value = body[i + 1];
            }
            maps.put(body[i].toString(), value);
        }
        return createToken(maps, adminSecret);
    }
    
    /**
     * 解析用户端Token
     *
     * @param token 要解析的用户端 JWT
     * @return 解析后的主体信息
     * @throws Exception 如果 Token 为空或解析失败，抛出异常
     */
    public static Claims parseUserToken(String token) throws Exception {
        return parseToken(token, userSecret);
    }
    
    /**
     * 解析管理员端Token
     *
     * @param token 要解析的管理员端 JWT
     * @return 解析后的主体信息
     * @throws Exception 如果 Token 为空或解析失败，抛出异常
     */
    public static Claims parseAdminToken(String token) throws Exception {
        return parseToken(token, adminSecret);
    }

    public static void main(String[] args) throws Exception {
        System.out.println(createUserToken("token", 1));
        parseAdminToken("eyJhbGciOiJIUzI1NiJ9.eyJ0b2tlbiI6eyJyYW5kb20iOiIxNzk4NjQ1NjAyMTQyMjYxMjQ4In0sImV4cCI6MTcxNzY2NzMwM30.mFphaqNf080R71_e5IYXIGkyvSgVe_E2GA4_vrWbe0Q");
        System.out.println("解析通过");
        parseUserToken("eyJhbGciOiJIUzI1NiJ9.eyJ0b2tlbiI6eyJyYW5kb20iOiIxNzk4NjQ1NjAyMTQyMjYxMjQ4In0sImV4cCI6MTcxNzY2NzMwM30.mFphaqNf080R71_e5IYXIGkyvSgVe_E2GA4_vrWbe0Q");

    }
}
